package com.pz.gulimall.ware.rabbitmq;

import com.pz.gulimall.common.constant.OrderStatusEnum;
import com.pz.gulimall.common.exception.BizCodeEnum;
import com.pz.gulimall.common.exception.RRException;
import com.pz.gulimall.common.to.LockStockResultTo;
import com.pz.gulimall.common.to.OrderStatusTo;
import com.pz.gulimall.common.to.mq.OrderPayFinishedMsg;
import com.pz.gulimall.common.to.mq.OrderReleaseTo;
import com.pz.gulimall.common.utils.R;
import com.pz.gulimall.ware.dao.WareSkuDao;
import com.pz.gulimall.ware.entity.resultMap.WareStockReleaseParam;
import com.pz.gulimall.ware.feign.OrderFeign;
import com.pz.gulimall.ware.service.WareSkuService;
import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.*;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.validation.constraints.NotEmpty;
import java.io.IOException;
import java.util.*;

import static com.pz.gulimall.ware.config.MQConfig.wareReleaseQueName;

@Component
@Slf4j
public class WareMq {
    @Resource
    private WareSkuDao wareSkuDao;

    /**
     * 主动接收订单取消的释放库存消息，避免order服务运行缓慢而导致永远无法释放库存(此时订单的状态已近确定修改为取消状态)
     */
    @RabbitListener(queues = wareReleaseQueName)
    @Transactional
    @RabbitHandler
    public void handleOrderRelease(OrderReleaseTo orderReleaseTo, Message msg, Channel channel) {
        log.info("收到订单已取消的消息-{}", orderReleaseTo);
        long deliveryTag = msg.getMessageProperties().getDeliveryTag();
        // 主动释放库存
        List<WareStockReleaseParam> releaseParams = new ArrayList<>();
        orderReleaseTo.getOrderItems().forEach(item -> {
            WareStockReleaseParam wareStockReleaseParam = new WareStockReleaseParam();
            wareStockReleaseParam.setSkuId(item.getSkuId());
            item.getWareDetails().forEach(detail -> {
                BeanUtils.copyProperties(detail, wareStockReleaseParam);
            });
            releaseParams.add(wareStockReleaseParam);
        });
        wareSkuDao.releaseStock(releaseParams);
        try {
            channel.basicAck(deliveryTag, false);
        } catch (IOException e) {
            throw new RRException(BizCodeEnum.RABBITMQ_ACK_EXCEPTION, e.getMessage());
        }
    }

    /**
     * 处理支付成功订单后的库存数据
     */
    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(name = "order.finnish.user.que"),
            exchange = @Exchange(name = "orderEvent.exchange", type = ExchangeTypes.TOPIC),
            key = {"order.finish.#"}
    ))
    @RabbitHandler
    public void handleOrderFinnishWare(OrderPayFinishedMsg finishedMsg, Message msg, Channel channel) {
        long deliveryTag = msg.getMessageProperties().getDeliveryTag();
        log.info("处理库存-{}", finishedMsg);
        try {
            channel.basicAck(deliveryTag, false);
        } catch (IOException e) {
            throw new RRException(BizCodeEnum.RABBITMQ_ACK_EXCEPTION, e.getMessage());
        }
    }
}
